Cosmos: Adds Cross-Region Hedging Design Spec to Driver Crate#4330
Conversation
NaluTripician
left a comment
There was a problem hiding this comment.
Cross-checked the spec against the actual .NET source in azure-cosmos-dotnet-v3 (CrossRegionHedgingAvailabilityStrategy.cs, AvailabilityStrategy.cs, DocumentClient.InitializePartitionLevelFailoverWithDefaultHedging). Overall the spec is well-grounded — author clearly read the .NET code, not just the docs. One material issue around the SDK-default write-hedging behavior on multi-master, plus a handful of minor nits inline.
…datta/3935_add_hedging_spec
There was a problem hiding this comment.
Pull request overview
Adds a new in-repo design specification (HEDGING_SPEC.md) to the Cosmos driver crate docs, describing the planned cross-region hedging (availability strategy) feature and its intended integration with existing routing/retry systems.
Changes:
- Adds a comprehensive design spec for cross-region request hedging (configuration, eligibility, algorithm, diagnostics, and phased rollout plan).
- Documents intended interactions with PPAF/PPCB, session consistency, throughput control, deadlines, and cancellation.
…datta/3935_add_hedging_spec
FabianMeiswinkel
left a comment
There was a problem hiding this comment.
LGTM except for few comments that could be addressed after merging the PR.
5f5d8c4
into
release/azure_data_cosmos-previews
…mbing Implements Part 1 of the cross-region hedging design spec (HEDGING_SPEC.md, merged via PR #4330). Pure data types and options plumbing only — no behavior change to the operation pipeline. Changes - New `src/options/availability_strategy.rs` with the public types from spec sections 4.1 and 4.2: `HedgeThreshold` (non-zero newtype), `HedgingStrategy`, and `AvailabilityStrategy`. - `OperationOptions` gains a public `availability_strategy: Option<AvailabilityStrategy>` field (spec section 4.3). The `CosmosOptions` derive auto-generates the matching `with_availability_strategy` builder method and view accessor, so the field participates in the existing environment → runtime → account → operation layered resolution. - `src/options/env_parsing.rs` gains `parse_hedging_threshold_from_env` and `parse_hedging_disabled_from_env` helpers for the two env vars defined in spec section 4.4. Both are gated `#[allow(dead_code)]` — they are consumed by the resolver introduced in Part 3. - `src/options/mod.rs` re-exports the three new public types. - New `docs/HEDGING_IMPLEMENTATION_PLAN.md` captures the 7-part rollout plan that this commit is Part 1 of. Account-level configuration uses the existing layered model: callers set `availability_strategy` on an `OperationOptions` value and pass it to `DriverOptionsBuilder::with_operation_options`. No new field on `DriverOptions` is required. Tests - 17 new unit tests covering `HedgeThreshold` invariants, builder round-trip, layered view resolution, and env-var parsing edge cases (unset, zero, non-numeric, empty, whitespace, case-insensitive matching). `cargo test -p azure_data_cosmos_driver --lib options::` reports 105 passed / 0 failed. - `cargo fmt`, `cargo build`, `cargo clippy --all-features --all-targets`, and `cargo doc --no-deps --all-features` all clean. Refs HEDGING_SPEC.md sections 4.1, 4.2, 4.3, 4.4, 11.3.1
Reconcile sdk/cosmos/azure_data_cosmos/docs/HEDGING_DETECTION_API_SPEC.md with the now-merged Rust hedging design spec (PR Azure#4330, on release/azure_data_cosmos-previews) and align it with the cross-SDK Hedging Detection API contract. Key updates: - Describe the cross-SDK contract generically (no SDK-specific naming) and add a Rust-to-contract mapping table. - requested_regions() now returns Vec<RequestedRegion> carrying a RequestedRegionReason, conforming to the contract's per-region-reason shape; add the public RequestedRegion struct and RequestedRegionReason enum plus a From<ExecutionContext> mapping. This resolves the previously-deferred per-region-reason question. - Correct the Retry to OperationRetry rename mechanics to the real code: ExecutionContext derives Serialize only (no Deserialize), and the hand-written as_str() must also be updated; serde(alias) is now conditional on adding Deserialize. - Fix the HedgeDiagnostics reconciliation: strategy_config and response_region are non-optional in the merged HEDGING_SPEC.md; fix the hedging_started() doc-comment that called as_ref() on a non-Option. - Correct the surface inventory: real dispatch-site paths, Serialize-only derive, and that regions_contacted() is sorted/deduped (so new accessors are needed for dispatch/completion order with duplicates). - Complete the file, which was truncated mid-section 8.2: finish the test plan and add section 9 (CHANGELOG drafts) and section 10 (open questions). Spec-only; no production code changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reconcile sdk/cosmos/azure_data_cosmos/docs/HEDGING_DETECTION_API_SPEC.md with the now-merged Rust hedging design spec (PR Azure#4330, on release/azure_data_cosmos-previews) and align it with the cross-SDK Hedging Detection API contract. Key updates: - Describe the cross-SDK contract generically (no SDK-specific naming) and add a Rust-to-contract mapping table. - requested_regions() now returns Vec<RequestedRegion> carrying a RequestedRegionReason, conforming to the contract's per-region-reason shape; add the public RequestedRegion struct and RequestedRegionReason enum plus a From<ExecutionContext> mapping. This resolves the previously-deferred per-region-reason question. - Correct the Retry to OperationRetry rename mechanics to the real code: ExecutionContext derives Serialize only (no Deserialize), and the hand-written as_str() must also be updated; serde(alias) is now conditional on adding Deserialize. - Fix the HedgeDiagnostics reconciliation: strategy_config and response_region are non-optional in the merged HEDGING_SPEC.md; fix the hedging_started() doc-comment that called as_ref() on a non-Option. - Correct the surface inventory: real dispatch-site paths, Serialize-only derive, and that regions_contacted() is sorted/deduped (so new accessors are needed for dispatch/completion order with duplicates). - Complete the file, which was truncated mid-section 8.2: finish the test plan and add section 9 (CHANGELOG drafts) and section 10 (open questions). Spec-only; no production code changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reconcile sdk/cosmos/azure_data_cosmos/docs/HEDGING_DETECTION_API_SPEC.md with the now-merged Rust hedging design spec (PR Azure#4330, on release/azure_data_cosmos-previews) and align it with the cross-SDK Hedging Detection API contract. Key updates: - Describe the cross-SDK contract generically (no SDK-specific naming) and add a Rust-to-contract mapping table. - requested_regions() now returns Vec<RequestedRegion> carrying a RequestedRegionReason, conforming to the contract's per-region-reason shape; add the public RequestedRegion struct and RequestedRegionReason enum plus a From<ExecutionContext> mapping. This resolves the previously-deferred per-region-reason question. - Correct the Retry to OperationRetry rename mechanics to the real code: ExecutionContext derives Serialize only (no Deserialize), and the hand-written as_str() must also be updated; serde(alias) is now conditional on adding Deserialize. - Fix the HedgeDiagnostics reconciliation: strategy_config and response_region are non-optional in the merged HEDGING_SPEC.md; fix the hedging_started() doc-comment that called as_ref() on a non-Option. - Correct the surface inventory: real dispatch-site paths, Serialize-only derive, and that regions_contacted() is sorted/deduped (so new accessors are needed for dispatch/completion order with duplicates). - Complete the file, which was truncated mid-section 8.2: finish the test plan and add section 9 (CHANGELOG drafts) and section 10 (open questions). Spec-only; no production code changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reconcile sdk/cosmos/azure_data_cosmos/docs/HEDGING_DETECTION_API_SPEC.md with the now-merged Rust hedging design spec (PR Azure#4330, on release/azure_data_cosmos-previews) and align it with the cross-SDK Hedging Detection API contract. Key updates: - Describe the cross-SDK contract generically (no SDK-specific naming) and add a Rust-to-contract mapping table. - requested_regions() now returns Vec<RequestedRegion> carrying a RequestedRegionReason, conforming to the contract's per-region-reason shape; add the public RequestedRegion struct and RequestedRegionReason enum plus a From<ExecutionContext> mapping. This resolves the previously-deferred per-region-reason question. - Correct the Retry to OperationRetry rename mechanics to the real code: ExecutionContext derives Serialize only (no Deserialize), and the hand-written as_str() must also be updated; serde(alias) is now conditional on adding Deserialize. - Fix the HedgeDiagnostics reconciliation: strategy_config and response_region are non-optional in the merged HEDGING_SPEC.md; fix the hedging_started() doc-comment that called as_ref() on a non-Option. - Correct the surface inventory: real dispatch-site paths, Serialize-only derive, and that regions_contacted() is sorted/deduped (so new accessors are needed for dispatch/completion order with duplicates). - Complete the file, which was truncated mid-section 8.2: finish the test plan and add section 9 (CHANGELOG drafts) and section 10 (open questions). Spec-only; no production code changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Adds
HEDGING_SPEC.mdto theazure_data_cosmos_drivercrate'sdocs/folder. This is a doc-only PR — no production code, no API changes, no test changes, noCargo.tomlchanges. Single file, +1569 lines.The spec is the design document for the cross-region hedging (
AvailabilityStrategy/HedgingStrategy) feature that will be implemented in a follow-up series of PRs. It is being landed on the previews branch ahead of implementation so reviewers can iterate on the design in-tree alongside the companion specs already there.Why hedging?
When a Cosmos DB region is degraded but not fully down (elevated tail latency, slow GC, partial network blip) the existing failover paths — PPAF (per-partition automatic failover) and PPCB (per-partition circuit breaker) — do not trigger because the region eventually returns successful responses. Applications see p99 / p99.9 latency spikes on requests routed to the slow region.
Cross-region hedging issues a speculative second request to an alternate region after a configurable threshold and returns whichever response arrives first, bounding tail latency at roughly
threshold + cross-region-RTT.Scope of this PR
In scope: Design document only.
Out of scope (follow-up PRs):
HedgingStrategy/AvailabilityStrategytypesshould_hedge()/is_final_result()pure functionsexecute_with_hedging()orchestratorHedgeDiagnosticscosmos_driver.rsWhat the spec covers (17 sections, ~1,569 lines)
CrossRegionHedgingAvailabilityStrategy), including PPAF/PPCB integrationHedgingStrategy, builder, environment variables)should_hedge()decision matrix) and default hedging enablement driven by PPAF with a full activation truth tablethreshold + N · step,tokio::select!race, drain loop403/403/3rows)ExcludeRegionsinvariant for retries inside a hedge)HedgeDiagnosticsshape, attachment contract, reservedcosmos.hedge.*tracing/metrics surface)tokio_util::sync::CancellationTokenhierarchy)Design highlights
does not auto-enable hedging — PPCB is failure-driven and does not by
itself signal a desire for latency hedging.
min(1000ms, request_timeout / 2)/500ms, mirroring .NET(Java's static
500ms / 100msis documented in the cross-SDK comparisonfor reference but not adopted).
tokio_util::sync::CancellationTokenfor cancellation,
Arc<Bytes>for zero-copy hedge body sharing.AvailabilityStrategy::Disabledenumvariant rather than .NET's nullable
TimeSpan?/ sentinel object pattern.HedgeDiagnosticsattached whenever a strategy was active,avoiding .NET's two-shape (fast-path vs drain-path) bookkeeping.
retry contract (§8.4), diagnostics attachment contract (§10.1),
preferred-regions precondition (§5.2).
cosmos.hedge.*for tracing eventsand metrics, ready for a future observability PR without breaking changes.
Cross-SDK alignment
The spec was reviewed against both the .NET v3 (
CrossRegionHedgingAvailabilityStrategy) and Java v4 (ThresholdBasedAvailabilityStrategy) implementations. Final alignment summary:min(1000ms, RT/2)/500ms500ms / 100msmin(1000ms, RT/2)/500ms(= .NET)Validation
Azure/azure-cosmos-dotnet-v3(main) andAzure/azure-sdk-for-java(main)§N.Nreferences resolve to existing spec sections.rs,.toml,Cargo.lock, or test changes; CI affecting only thedoc-render job
Branch / target
users/kundadebdatta/3935_add_hedging_specrelease/azure_data_cosmos-previewsCode changes to add hedging spec.→Code changes to update hedging spec.)Follow-up work tracker
The implementation will land in subsequent PRs roughly tracking §16 phases:
HedgingStrategytypes +should_hedge()+is_final_result()